package com.attendance.www.hr.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang.time.DateUtils;
import org.springframework.stereotype.Service;

import com.attendance.www.hr.beans.AttendanceBean;
import com.attendance.www.hr.beans.EmployeeBean;
import com.attendance.www.hr.beans.SchedulWeekBean;
import com.attendance.www.hr.constant.AppConstant;
import com.attendance.www.hr.dao.mapper.AccessInvalidLogsMapper;
import com.attendance.www.hr.dao.mapper.AttendanceExtMapper;
import com.attendance.www.hr.dao.mapper.AttendanceMapper;
import com.attendance.www.hr.dao.mapper.CheckinoutMorningExtMapper;
import com.attendance.www.hr.dao.mapper.CheckinoutMorningMapper;
import com.attendance.www.hr.dao.mapper.EmployeeMapper;
import com.attendance.www.hr.dao.mapper.EmployeeSchedulExtMapper;
import com.attendance.www.hr.dao.mapper.EmployeeSchedulMapper;
import com.attendance.www.hr.dao.mapper.NoEmployeeAttendanceExtMapper;
import com.attendance.www.hr.dao.mapper.NoEmployeeAttendanceMapper;
import com.attendance.www.hr.dao.mapper.PunchTimeMapper;
import com.attendance.www.hr.dao.mapper.RetroactiveMapper;
import com.attendance.www.hr.dao.mapper.SchedulDayMapper;
import com.attendance.www.hr.dao.mapper.SchedulWeekExtMapper;
import com.attendance.www.hr.dao.mapper.SystemConfigureMapper;
import com.attendance.www.hr.dao.mapper.TaskMapper;
import com.attendance.www.hr.entitys.AccessInvalidLogs;
import com.attendance.www.hr.entitys.Attendance;
import com.attendance.www.hr.entitys.AttendanceExample;
import com.attendance.www.hr.entitys.CheckinoutMorning;
import com.attendance.www.hr.entitys.Employee;
import com.attendance.www.hr.entitys.EmployeeExample;
import com.attendance.www.hr.entitys.EmployeeSchedul;
import com.attendance.www.hr.entitys.EmployeeSchedulExample;
import com.attendance.www.hr.entitys.NoEmployeeAttendanceExample;
import com.attendance.www.hr.entitys.NoEmployeeAttendanceExt;
import com.attendance.www.hr.entitys.PunchTime;
import com.attendance.www.hr.entitys.PunchTimeExample;
import com.attendance.www.hr.entitys.RetroactiveExample;
import com.attendance.www.hr.entitys.SchedulDayExample;
import com.attendance.www.hr.entitys.SchedulDayKey;
import com.attendance.www.hr.entitys.SystemConfigure;
import com.attendance.www.hr.entitys.Task;
import com.attendance.www.hr.entitys.TaskExample;
import com.attendance.www.hr.service.IAccessService;
import com.attendance.www.hr.service.IApprovalService;
import com.attendance.www.hr.service.IAttendanceService;
import com.attendance.www.hr.utils.AccessUtils;
import com.attendance.www.hr.utils.MailUtils;
import com.attendance.www.hr.utils.TimeUtils;
import com.attendance.www.hr.utils.ToolUtils;

@Service
public class AccessServiceImpl implements IAccessService {

	@Resource
	private EmployeeMapper employeeDao;
	@Resource
	private AttendanceMapper attendanceDao;
	@Resource
	private AttendanceExtMapper attendanceExtDao;
	@Resource
	private IAttendanceService attendanceService;
	@Resource
	private IApprovalService approvalService;
	@Resource
	private EmployeeSchedulMapper employeeSchedulDao;
	@Resource
	private PunchTimeMapper punchTimeDao;
	@Resource
	private SchedulDayMapper schedulDayDao;
	@Resource
	private NoEmployeeAttendanceMapper noEmployeeAttendanceDao;
	@Resource
	private AccessInvalidLogsMapper accessInvalidLogsDao;
	@Resource
	private NoEmployeeAttendanceExtMapper noEmployeeAttendanceExtDao;
	@Resource
	private SystemConfigureMapper systemConfigureDao;
	@Resource
	private CheckinoutMorningMapper checkinoutMorningDao;
	@Resource
	private CheckinoutMorningExtMapper checkinoutMorningExtDao;
	@Resource
	private TaskMapper taskDao;
	@Resource
	private EmployeeSchedulExtMapper employeeSchedulExtDao;
	@Resource
	private SchedulWeekExtMapper schedulWeekExtDao;
	@Resource
	private RetroactiveMapper retroactiveDao;

	/**
	 * 自动保存考勤数据
	 */
	@Override
	public boolean saveAttendaceAuto(Date attDate, Integer employeeId) {
		// 日期减一，昨天考勤时间
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(attDate);
		calendar.add(Calendar.DATE, -1);

		// 查询前一天员工和班次关系表
		List<EmployeeBean> employeeBeanYesterdayList = employeeSchedulExtDao
				.selectEmployeeSchedulListByDate(calendar.getTime());

		// 添加数据库成功后保存到MAP集合中
		Map<String, Date> employeeIdDateMap = new HashMap<>();
		// 读取考勤数据
		List<CheckinoutMorning> cmList = AccessUtils.getAccessInfoMorning(AppConstant.ACCESS_ADDRESS1, attDate);
		Map<String, AttendanceBean> attMap = AccessUtils.getAccessInfo(AppConstant.ACCESS_ADDRESS1, attDate,
				employeeBeanYesterdayList);

		// 读取失败
		if (attMap.containsKey(AccessUtils.failedKey)) {
			// 失效的地址
			String address = attMap.get(AccessUtils.failedKey).getAddress();
			String errorMessage = attMap.get(AccessUtils.failedKey).getErrorMessage();
			// 查询初始化表
			SystemConfigure systemConfigure = systemConfigureDao.selectByPrimaryKey(1);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			String textPart = sdf.format(new Date()) + "，自动导入考勤失败，请管理员查明原因手动处理。";// 正文
			// 发Email
			boolean isSucceed = MailUtils.send(systemConfigure, systemConfigure.getMailReceive(),
					AppConstant.MAIL_TITLE, textPart, AppConstant.MAIL_ENDING);

			// 记录失效日期，地址等数据
			AccessInvalidLogs ail = new AccessInvalidLogs();
			ail.setEmailInformation(textPart);
			if (isSucceed) {
				ail.setEmailState(1);//
			} else {
				ail.setEmailState(0);// 失败0
			}
			ail.setInvalidLogsAddress(address);
			ail.setErrorMessage(errorMessage);
			ail.setInvalidLogsDate(new Date());
			accessInvalidLogsDao.insertSelective(ail);
			return false;
		}

		// 保存考勤信息
		/*
		 * Calendar calStartDate = Calendar.getInstance();
		 * calStartDate.setTime(DateUtils.addDays(new Date(), -1));
		 * calStartDate.set(Calendar.HOUR_OF_DAY,0);
		 * calStartDate.set(Calendar.MINUTE,0); calStartDate.set(Calendar.SECOND,0);
		 * calStartDate.set(Calendar.MILLISECOND,0);
		 */
		// Date attDate=calStartDate.getTime();//考勤日期
		// HR数据库中未录入的人员考勤信息（补漏）
		Map<String, Integer> neaMap = new HashMap<>();
		/*
		 * List<NoEmployeeAttendance> neaList =
		 * noEmployeeAttendanceDao.selectByExample(new NoEmployeeAttendanceExample());
		 * for (NoEmployeeAttendance noEmployeeAttendance : neaList) {
		 * neaMap.put(noEmployeeAttendance.getNoEmployeeNo(), 1); }
		 */
		// HR数据库中未录入的人员考勤信息（补漏）
		List<NoEmployeeAttendanceExt> neaExtList = noEmployeeAttendanceExtDao.selectNoEmployeeAttendance();
		List<Integer> noEmployeeIdList = new ArrayList<Integer>();
		Date noEmployeeAttendanceDate = null;
		List<Attendance> attendanceNoList = null;
		if (neaExtList.size() > 0) {
			// 获取最小日期
			noEmployeeAttendanceDate = neaExtList.get(0).getNoEmployeeAttendanceDate();
			// 处理人员ID集合
			for (int i = 0; i < neaExtList.size(); i++) {
				boolean type = true;
				for (int j = 0; j < noEmployeeIdList.size(); j++) {
					if (neaExtList.get(i).getEmployeeId().equals(noEmployeeIdList.get(j))) {
						type = false;
						break;
					}
				}
				if (type) {
					noEmployeeIdList.add(neaExtList.get(i).getEmployeeId());
				}
				neaMap.put(neaExtList.get(i).getNoEmployeeNo(), 1);
			}

			// 查询考勤信息
			AttendanceExample attendanceExample = new AttendanceExample();
			attendanceExample.createCriteria().andEmployeeIdIn(noEmployeeIdList)
					.andAttendanceDateBetween(noEmployeeAttendanceDate, attDate);
			attendanceNoList = attendanceDao.selectByExample(attendanceExample);
		}

		// 查所有考勤日在职人员集合
		EmployeeExample employeeExample = new EmployeeExample();
		employeeExample.or().andEntryDateLessThanOrEqualTo(attDate).andEmployeeSeparatedDateIsNull();
		employeeExample.or().andEntryDateLessThanOrEqualTo(attDate)
				.andEmployeeSeparatedDateGreaterThanOrEqualTo(attDate);
		List<Employee> empList = employeeDao.selectByExample(employeeExample);
		// 如果是根据某个人处理考勤信息时，过滤人员ID
		if (employeeId != null) {
			empList = empList.stream().filter(s -> s.getEmployeeId().equals(employeeId)).collect(Collectors.toList());
		}

		// 在职人员Map
		Map<Integer, String> empMap = new HashMap<>();
		for (Employee employee : empList) {
			empMap.put(employee.getEmployeeId(), employee.getEmployeeNo());
		}
		// 查询当日的已存在的考勤记录
		AttendanceExample attendanceExample = new AttendanceExample();
		attendanceExample.createCriteria().andAttendanceDateEqualTo(attDate);
		List<Attendance> attendanceList = attendanceDao.selectByExample(attendanceExample);

		// 查询昨天的已存在的考勤记录
		attendanceExample = new AttendanceExample();
		attendanceExample.createCriteria().andAttendanceDateEqualTo(calendar.getTime());
		List<Attendance> attendanceYesterdayList = attendanceDao.selectByExample(attendanceExample);

		// 查询班次
		List<SchedulWeekBean> schedulWeekBeanList = schedulWeekExtDao.getSchedulWeekEmployeeListByDate(attDate);

		// 已生成的考勤Map
		Map<String, Attendance> attendanceMap = new HashMap<>();
		for (Attendance attendance : attendanceList) {
			String employeeNo = empMap.get(attendance.getEmployeeId());
			attendanceMap.put(employeeNo, attendance);
			// 添加到MAP集合
			String key = attendance.getEmployeeId() + "&" + ToolUtils.dateToStr(attendance.getAttendanceDate());
			employeeIdDateMap.put(key, attendance.getAttendanceDate());
		}

		List<Integer> employeeIdList = new ArrayList<>();
		Integer record = null;
		for (Employee employee : empList) {
			employeeIdList.add(employee.getEmployeeId());
			String employeeNo = employee.getEmployeeNo();
			AttendanceBean attendanceBean = attMap.get(employeeNo);
			if (attendanceBean != null) {
				if (attendanceMap.get(employeeNo) == null) {
					Attendance attendance = new Attendance();
					attendance.setEmployeeId(employee.getEmployeeId());
					attendance.setAttendanceDate(attendanceBean.getAttendanceDate());
					attendance.setOriginalStartTime(attendanceBean.getStartTime());
					attendance.setStartTime(attendanceBean.getStartTime());
					attendance.setOriginalEndTime(attendanceBean.getEndTime());
					attendance.setEndTime(attendanceBean.getEndTime());
					attendance.setAddress(attendanceBean.getAddress());
					String key = attendance.getEmployeeId() + "&" + ToolUtils.dateToStr(attendance.getAttendanceDate());

					// 判断如果是跨天考勤时间
					List<EmployeeBean> ebList = employeeBeanYesterdayList.stream()
							.filter(s -> s.getEmployeeNo().equals(employeeNo))
							.sorted(Comparator.comparing(EmployeeBean::getFromDate).reversed())
							.collect(Collectors.toList());
					if (ebList.size() > 0) {
						EmployeeBean employeeBean = ebList.get(0);
						if (TimeUtils.compareTime(employeeBean.getStartFromTime(),
								employeeBean.getEndFromTime()) == 1) {
							// 获取昨天考勤信息
							List<Attendance> ayList = attendanceYesterdayList.stream()
									.filter(s -> s.getEmployeeId().equals(attendance.getEmployeeId()))
									.collect(Collectors.toList());
							if (ayList.size() > 0) {
								if (ayList.get(0).getOriginalStartTime() != null
										&& attendance.getOriginalEndTime() != null) {
									// 判断打开时间
									if (TimeUtils.compareTime(ayList.get(0).getOriginalStartTime(),
											attendance.getOriginalEndTime()) == 1) {
										attendance.setAttendanceId(ayList.get(0).getAttendanceId());
										attendance.setAttendanceDate(ayList.get(0).getAttendanceDate());
										attendance.setOriginalStartTime(null);
										attendance.setStartTime(null);
										attendanceDao.updateByPrimaryKeySelective(attendance);
										attMap.remove(employeeNo);
										continue;
									}
								}
							}

							// 判断日期内是否存在班次
							// 人员
							List<SchedulWeekBean> swbList = schedulWeekBeanList.stream()
									.filter(s -> s.getEmployeeId().equals(attendance.getEmployeeId()))
									.collect(Collectors.toList());
							// 日期
							List<SchedulWeekBean> swList = swbList.stream().filter(s -> true == TimeUtils
									.dateCalendar(attendance.getAttendanceDate(), s.getFromDate(), s.getThruDate()))
									.collect(Collectors.toList());
							if (swList.size() > 0) {
								EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
								employeeSchedulExample.createCriteria().andSwIdEqualTo(swList.get(0).getSwId())
										.andEmployeeIdEqualTo(swList.get(0).getEmployeeId())
										.andFromDateLessThanOrEqualTo(attendance.getAttendanceDate())
										.andThruDateGreaterThanOrEqualTo(attendance.getAttendanceDate());
								List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao
										.selectByExample(employeeSchedulExample);
								// 判断是否包含员工ID
								if (employeeSchedulList.size() <= 0) {
									attMap.remove(employeeNo);
									continue;
								}
							}
						} else {
							// 判断班次内是否有员工日期
							/*
							 * if (schedulWeekBeanList.size() > 0) { // 人员 List<SchedulWeekBean> swbList =
							 * schedulWeekBeanList.stream() .filter(s ->
							 * s.getEmployeeId().equals(attendance.getEmployeeId()))
							 * .collect(Collectors.toList()); // 日期 List<SchedulWeekBean> swList =
							 * swbList.stream().filter(s -> true == TimeUtils
							 * .dateCalendar(attendance.getAttendanceDate(), s.getFromDate(),
							 * s.getThruDate())) .collect(Collectors.toList()); if (swList.size() > 0) {
							 * EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
							 * employeeSchedulExample.createCriteria().andSwIdEqualTo(swList.get(0).getSwId(
							 * )) .andEmployeeIdEqualTo(swList.get(0).getEmployeeId())
							 * .andFromDateLessThanOrEqualTo(attendance.getAttendanceDate())
							 * .andThruDateGreaterThanOrEqualTo(attendance.getAttendanceDate());
							 * List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao
							 * .selectByExample(employeeSchedulExample); // 判断是否包含员工ID if
							 * (employeeSchedulList.size() <= 0) { //
							 * System.out.println(ToolUtils.dateToStr(attendance.getAttendanceDate())); //
							 * List<EmployeeSchedul> sdayList = employeeSchedulList.stream().filter(s -> //
							 * true == //
							 * TimeUtils.dateCalendar(attendance.getAttendanceDate(),s.getFromDate(), //
							 * s.getThruDate())).collect(Collectors.toList()); // if(sdayList.size()<=0) {
							 * attMap.remove(employeeNo); continue; // } } } }
							 */
						}
					}

					// 判断MAP是否存在该日期，如果存在不新增数据，以免重复数据出现
					if (employeeIdDateMap.get(key) == null) {
						// 查询是否当天存在考勤
						AttendanceExample atExample = new AttendanceExample();
						atExample.createCriteria().andAttendanceDateEqualTo(attendance.getAttendanceDate())
								.andEmployeeIdEqualTo(attendance.getEmployeeId());
						if (attendanceDao.countByExample(atExample) <= 0) {
							record = attendanceDao.insertSelective(attendance);
						} else {
							record = attendanceDao.updateByExampleSelective(attendance, atExample);
						}
						if (record <= 0) {
							return false;
						}
					}
					attMap.remove(employeeNo);
				} else {// 已有考勤，更新考勤
					Attendance attendance = attendanceMap.get(employeeNo);
					attendance.setOriginalStartTime(attendanceBean.getStartTime());
					attendance.setStartTime(attendanceBean.getStartTime());
					attendance.setOriginalEndTime(attendanceBean.getEndTime());
					attendance.setEndTime(attendanceBean.getEndTime());
					attendance.setAddress(attendanceBean.getAddress());
					record = attendanceDao.updateByPrimaryKeySelective(attendance);
					if (record <= 0) {
						return false;
					} else {
						attMap.remove(employeeNo);
					}
				}
			}
			// 判断是否有未插入的考勤
			Integer neaValue = neaMap.get(employeeNo);
			if (neaValue != null) {
				for (NoEmployeeAttendanceExt nea : neaExtList) {
					if (nea.getNoEmployeeNo().equals(employeeNo)) {
						Integer attendanceId = null;
						// 查询考勤记录是否存在
						for (int io = 0; io < attendanceNoList.size(); io++) {
							// 判断人员ID和日期是否相同
							Attendance attendance = attendanceNoList.get(io);
							if (attendance.getEmployeeId().equals(nea.getEmployeeId())
									&& attendance.getAttendanceDate().equals(nea.getNoEmployeeAttendanceDate())) {
								attendanceId = attendance.getAttendanceId();
								break;
							}
						}
						// 新增
						if (attendanceId == null) {
							Attendance attendance = new Attendance();
							attendance.setEmployeeId(nea.getEmployeeId());
							attendance.setAttendanceDate(nea.getNoEmployeeAttendanceDate());
							attendance.setOriginalStartTime(nea.getOriginalStartTime());
							attendance.setStartTime(nea.getOriginalStartTime());
							attendance.setOriginalEndTime(nea.getOriginalEndTime());
							attendance.setEndTime(nea.getOriginalEndTime());
							attendance.setAddress(nea.getAddress());
							String key = attendance.getEmployeeId() + "&"
									+ ToolUtils.dateToStr(attendance.getAttendanceDate());
							if (employeeIdDateMap.get(key) == null) {
								int record2 = 0;
								AttendanceExample atExample = new AttendanceExample();
								atExample.createCriteria().andAttendanceDateEqualTo(attendance.getAttendanceDate())
										.andEmployeeIdEqualTo(attendance.getEmployeeId());
								if (attendanceDao.countByExample(atExample) <= 0) {
									record2 = attendanceDao.insertSelective(attendance);
								} else {
									record2 = attendanceDao.updateByExampleSelective(attendance, atExample);
								}
								if (record2 <= 0) {
									return false;
								} else {
									employeeIdDateMap.put(key, attendance.getAttendanceDate());
								}
							}
							// 插入成功，删除数据
							// noEmployeeAttendanceDao.deleteByPrimaryKey(nea.getNoEmployeeAttendanceId());
						}
						// 修改
						else {
							Attendance attendance = new Attendance();
							attendance.setAttendanceId(attendanceId);
							attendance.setEmployeeId(nea.getEmployeeId());
							attendance.setAttendanceDate(nea.getNoEmployeeAttendanceDate());
							attendance.setOriginalStartTime(nea.getOriginalStartTime());
							attendance.setStartTime(nea.getOriginalStartTime());
							attendance.setOriginalEndTime(nea.getOriginalEndTime());
							attendance.setEndTime(nea.getOriginalEndTime());
							attendance.setAddress(nea.getAddress());
							attendance.setUpdateTime(new Date());
							int record2 = attendanceDao.updateByPrimaryKeySelective(attendance);
							if (record2 <= 0) {
								return false;
							} else {// 插入成功，删除数据
								// noEmployeeAttendanceDao.deleteByPrimaryKey(nea.getNoEmployeeAttendanceId());
							}
						}
						// 新增遗漏的考勤人员--日期，插入任务表
						approvalService.insertTaskByParam(nea.getNoEmployeeAttendanceDate(), nea.getEmployeeId());
					}
				}
			}
		}

		// 保存未在HR数据库中新增的（刚入职）人员的考勤信息
		Set<String> employeeNoKey = attMap.keySet();
		// 由于一天导入两次，所以先删除前一次的数据，再插入; 2018-05-31update
		if (attMap.size() > 0) {
			NoEmployeeAttendanceExample neaExample = new NoEmployeeAttendanceExample();
			neaExample.createCriteria().andNoEmployeeAttendanceDateEqualTo(attDate);
			// noEmployeeAttendanceDao.deleteByExample(neaExample);
		}

		/*
		 * Iterator<String> iter = employeeNoKey.iterator(); while (iter.hasNext()) {
		 * String key = iter.next(); AttendanceBean attendanceBean = attMap.get(key);
		 * NoEmployeeAttendance nea = new NoEmployeeAttendance();
		 * nea.setNoEmployeeNo(attendanceBean.getEmployeeNo());
		 * nea.setNoEmployeeAttendanceDate(attendanceBean.getAttendanceDate());
		 * nea.setOriginalStartTime(attendanceBean.getStartTime());
		 * nea.setOriginalEndTime(attendanceBean.getEndTime());
		 * nea.setAddress(attendanceBean.getAddress());
		 * noEmployeeAttendanceDao.insertSelective(nea); }
		 */

		// 考勤日期
		Map<Date, Date> attendanceDateMap = new HashMap<>();
		attendanceDateMap.put(attDate, attDate);

		// 查询班次情况
		EmployeeSchedulExample employeeSchedulExample = new EmployeeSchedulExample();
		employeeSchedulExample.setOrderByClause("employee_id asc,from_date desc");
		if (employeeId != null) {
			employeeSchedulExample.createCriteria().andEmployeeIdEqualTo(employeeId);
		}
		List<EmployeeSchedul> employeeSchedulList = employeeSchedulDao.selectByExample(employeeSchedulExample);
		List<Integer> swIdList = new ArrayList<Integer>();
		Map<Integer, List<EmployeeSchedul>> employeeSchedulMap = new HashMap<Integer, List<EmployeeSchedul>>();
		for (int ei = 0; ei < employeeSchedulList.size(); ei++) {
			if (employeeSchedulMap.containsKey(employeeSchedulList.get(ei).getEmployeeId())) {
				List<EmployeeSchedul> eList = employeeSchedulMap.get(employeeSchedulList.get(ei).getEmployeeId());
				eList.add(employeeSchedulList.get(ei));
				employeeSchedulMap.put(employeeSchedulList.get(ei).getEmployeeId(), eList);
			} else {
				List<EmployeeSchedul> eList = new ArrayList<EmployeeSchedul>();
				eList.add(employeeSchedulList.get(ei));
				employeeSchedulMap.put(employeeSchedulList.get(ei).getEmployeeId(), eList);
			}
			swIdList.add(employeeSchedulList.get(ei).getSwId());
		}

		// 查询考勤打卡
		List<PunchTime> punchTimeList = punchTimeDao.selectByExample(new PunchTimeExample());
		Map<Integer, PunchTime> punchTimeMap = new HashMap<Integer, PunchTime>();
		for (int pi = 0; pi < punchTimeList.size(); pi++) {
			punchTimeMap.put(punchTimeList.get(pi).getPunchTimeId(), punchTimeList.get(pi));
		}

		// 查询班次日期
		SchedulDayExample schedulDayExample = new SchedulDayExample();
		schedulDayExample.createCriteria().andSwIdIn(swIdList);
		List<SchedulDayKey> schedulDayKeyList = schedulDayDao.selectByExample(schedulDayExample);
		Map<Integer, List<SchedulDayKey>> schedulDayKeyMap = new HashMap<Integer, List<SchedulDayKey>>();
		for (int si = 0; si < schedulDayKeyList.size(); si++) {
			if (schedulDayKeyMap.containsKey(schedulDayKeyList.get(si).getSwId())) {
				List<SchedulDayKey> lList = schedulDayKeyMap.get(schedulDayKeyList.get(si).getSwId());
				lList.add(schedulDayKeyList.get(si));
				schedulDayKeyMap.put(schedulDayKeyList.get(si).getSwId(), lList);
			} else {
				List<SchedulDayKey> lList = new ArrayList<SchedulDayKey>();
				lList.add(schedulDayKeyList.get(si));
				schedulDayKeyMap.put(schedulDayKeyList.get(si).getSwId(), lList);
			}
		}

		// 生成旷工人员考勤信息
		/*
		 * attendanceService.addNotAttendanceDate(attendanceDateMap, employeeIdList,
		 * employeeSchedulMap, schedulDayKeyMap, punchTimeMap);
		 */

		// 判断未导入成功员工的日期是否不为空，重新计算他们的考勤
		if (noEmployeeAttendanceDate != null) {
			if (noEmployeeIdList.size() > 0) {
				// approvalService.resetAttendance(noEmployeeAttendanceDate, attDate,
				// noEmployeeIdList);
			}
		}

		List<Integer> idList = checkinoutMorningExtDao.getCheckinoutMorningId(attDate);
		if (idList.size() > 0) {
			// 删除多次导入产生的重复数据
			record = checkinoutMorningExtDao.deleteDuplicatedData(attDate);
		}

		// 保存早上打卡信息
		for (CheckinoutMorning checkinoutMorning : cmList) {
			checkinoutMorningDao.insertSelective(checkinoutMorning);
		}

		// 重计算
		approvalService.resetAttendance(calendar.getTime(), DateUtils.addDays(attDate, 1), employeeIdList);
		return true;
	}

	public static boolean sameDate(Date d1, Date d2) {
		if (null == d1 || null == d2)
			return false;
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(d1);
		cal1.set(Calendar.HOUR_OF_DAY, 0);
		cal1.set(Calendar.MINUTE, 0);
		cal1.set(Calendar.SECOND, 0);
		cal1.set(Calendar.MILLISECOND, 0);
		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(d2);
		cal2.set(Calendar.HOUR_OF_DAY, 0);
		cal2.set(Calendar.MINUTE, 0);
		cal2.set(Calendar.SECOND, 0);
		cal2.set(Calendar.MILLISECOND, 0);
		return cal1.getTime().equals(cal2.getTime());
	}

	/**
	 * 导入当天和前3天的考勤
	 */
	@Override
	public boolean saveAttendaceAutoDays() {
		boolean isSuccess = false;
		Calendar calStartDate = Calendar.getInstance();
		// calStartDate.setTime(DateUtils.addDays(new Date(), -1));
		calStartDate.setTime(new Date());
		calStartDate.set(Calendar.HOUR_OF_DAY, 0);
		calStartDate.set(Calendar.MINUTE, 0);
		calStartDate.set(Calendar.SECOND, 0);
		calStartDate.set(Calendar.MILLISECOND, 0);
		Date attDate = calStartDate.getTime();// 考勤日期
		// 循环执行三天内读取考勤
		for (int i = 0; i < 2; i++) {
			isSuccess = this.saveAttendaceAuto(attDate, null);
			attDate = DateUtils.addDays(attDate, -1);
		}
		// this.deleteAttendance();
		// 处理当天考勤状态
		approvalService.todayAttendance(new Date(), null);
		return isSuccess;
	}

	/**
	 * 手动重新生成某日的考勤 同时在任务表添加日期
	 */
	@Override
	public boolean saveAttendaceByDate(Date attDate) {
		// 插入任务表数据
		TaskExample taskExample = new TaskExample();
		taskExample.createCriteria().andTaskDateEqualTo(attDate).andStateEqualTo(3);
		List<Task> taskList = taskDao.selectByExample(taskExample);// 查询是否已有数据
		if (taskList.size() == 0) {
			Task task = new Task();
			task.setState(3);
			task.setTaskDate(attDate);
			taskDao.insertSelective(task);
		}
		// this.deleteAttendance(attDate);
		// 生成考勤
		this.saveAttendaceAuto(attDate, null);
		// 处理当天考勤状态
		approvalService.todayAttendance(new Date(), null);
		return true;
	}

	/**
	 * 删除多余考勤数据
	 */
	@Override
	public void deleteAttendance() {
		// 删除不是在员工入职日期后的考勤日期
		List<Integer> attendanceIdList = attendanceExtDao.getAttendanceIdList();
		// 获取员工离职后，生成的考勤数据
		attendanceIdList.addAll(attendanceExtDao.getAttendanceIdListByEmployeeIsSeparated());
		if (attendanceIdList != null && attendanceIdList.size() > 0) {
			AttendanceExample attendanceExample = new AttendanceExample();
			attendanceExample.createCriteria().andAttendanceIdIn(attendanceIdList);
			attendanceDao.deleteByExample(attendanceExample);
		}
	}

	/**
	 * 删除重复考勤
	 */
	@Override
	public void repeatAttendace() {
		// 获取当月重复考勤记录
		List<AttendanceBean> attendanceBeanList = attendanceExtDao.getRepeatAttendaceList();
		for (int i = 0; i < attendanceBeanList.size(); i++) {
			AttendanceBean attendanceBean = attendanceBeanList.get(i);
			// 员工ID和日期查询重复考勤
			AttendanceExample atendanceExample = new AttendanceExample();
			atendanceExample.createCriteria().andEmployeeIdEqualTo(attendanceBean.getEmployeeId())
					.andAttendanceDateEqualTo(attendanceBean.getAttendanceDate());
			List<Attendance> attendanceList = attendanceDao.selectByExample(atendanceExample);
			if (attendanceList.size() > 0) {
				// 验证是否考勤已补签
				for (int j = 0; j < attendanceList.size(); j++) {
					// 如果不存在补签，删除重复考勤记录
					RetroactiveExample retroactiveExample = new RetroactiveExample();
					retroactiveExample.createCriteria().andEmployeeIdEqualTo(attendanceBean.getEmployeeId())
							.andAttendanceIdEqualTo(attendanceList.get(j).getAttendanceId());
					if (retroactiveDao.countByExample(retroactiveExample) <= 0) {
						attendanceDao.deleteByPrimaryKey(attendanceList.get(j).getAttendanceId());
						List<Integer> employeeIdList = new ArrayList<>();
						employeeIdList.add(attendanceBean.getEmployeeId());
						// 重计算
						approvalService.resetAttendance(attendanceList.get(j).getAttendanceDate(),
								attendanceList.get(j).getAttendanceDate(), employeeIdList);
						break;
					}
				}
			}
		}
	}
}
